<!DOCTYPE html>


<html lang="zh_CN">
  

    <head>
      <meta charset="utf-8" />
        
      <meta
        name="viewport"
        content="width=device-width, initial-scale=1, maximum-scale=1"
      />
      <title>Hystrix断路器 |  MyBlog</title>
  <meta name="generator" content="hexo-theme-ayer">
      
      <link rel="shortcut icon" href="/favicon.ico" />
       
<link rel="stylesheet" href="/dist/main.css">

      <link
        rel="stylesheet"
        href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css"
      />
      
<link rel="stylesheet" href="/css/custom.css">
 
      <script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>
       
 

      <link
        rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/@sweetalert2/theme-bulma@5.0.1/bulma.min.css"
      />
      <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.0.19/dist/sweetalert2.min.js"></script>

      <!-- mermaid -->
      
      <style>
        .swal2-styled.swal2-confirm {
          font-size: 1.6rem;
        }
      </style>
    <link rel="alternate" href="/atom.xml" title="MyBlog" type="application/atom+xml">
</head>
  </html>
</html>


<body>
  <div id="app">
    
      
    <main class="content on">
      <section class="outer">
  <article
  id="SpringCloud-SpringCloud-Hystrix断路器"
  class="article article-type-SpringCloud"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h1 class="article-title sea-center" style="border-left:0" itemprop="name">
  Hystrix断路器
</h1>
 

      
    </header>
     
    <div class="article-meta">
      <a href="/2022/03/12/SpringCloud-Hystrix%E6%96%AD%E8%B7%AF%E5%99%A8/" class="article-date">
  <time datetime="2022-03-12T14:28:20.000Z" itemprop="datePublished">2022-03-12</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/SpringCloud/">SpringCloud</a>
  </div>
  
<div class="word_count">
    <span class="post-time">
        <span class="post-meta-item-icon">
            <i class="ri-quill-pen-line"></i>
            <span class="post-meta-item-text"> 字数统计:</span>
            <span class="post-count">6.4k</span>
        </span>
    </span>

    <span class="post-time">
        &nbsp; | &nbsp;
        <span class="post-meta-item-icon">
            <i class="ri-book-open-line"></i>
            <span class="post-meta-item-text"> 阅读时长≈</span>
            <span class="post-count">28 分钟</span>
        </span>
    </span>
</div>
 
    </div>
      
    <div class="tocbot"></div>




  
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="十、Hystrix断路器"><a href="#十、Hystrix断路器" class="headerlink" title="十、Hystrix断路器"></a>十、Hystrix断路器</h1><h2 id="10-1-概述"><a href="#10-1-概述" class="headerlink" title="10.1.概述"></a>10.1.概述</h2><h3 id="10-1-1-分布式系统面临的问题"><a href="#10-1-1-分布式系统面临的问题" class="headerlink" title="10.1.1.分布式系统面临的问题"></a>10.1.1.分布式系统面临的问题</h3><p><strong>复杂分布式体系结构中的应用程序有数十个依赖关系，每个依赖关系在某些时候将不可避免地失败。</strong></p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203022122602.png" alt="image-20220302212250401"></p>
<blockquote>
<p>服务雪崩</p>
</blockquote>
<p>多个微服务之间调用的时候，假设微服务A调用微服务B和微服务C，微服务B和微服务C又调用其它的微服务，这就是所谓的<strong>“扇出”</strong>。如果扇出的链路上某个微服务的调用<strong>响应时间过长或者不可用</strong>，对<strong>微服务A的调用就会占用越来越多的系统资源</strong>，进而引起系统崩溃，所谓的“雪崩效应”.</p>
<p>对于高流量的应用来说，单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是，这些应用程序还可能导致服务之间的延迟增加，备份队列，线程和其他系统资源紧张，导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理，以便单个依赖关系的失败，不能取消整个应用程序或系统。<br>所以，<br>通常当你发现一个模块下的某个实例失败后，这时候这个模块依然还会接收流量，然后这个有问题的模块还调用了其他的模块，这样就会发生<strong>级联故障</strong>，或者叫雪崩。</p>
<h3 id="10-1-2-Hystrix是什么"><a href="#10-1-2-Hystrix是什么" class="headerlink" title="10.1.2.Hystrix是什么"></a>10.1.2.Hystrix是什么</h3><p>Hystrix是一个用于<strong>处理分布式系统的延迟和容错的开源库</strong>，在分布式系统里，许多依赖不可避免的会调用失败，比如超时、异常等，Hystrix能够<strong>保证在一个依赖出问题的情况下，不会导致整体服务失败</strong>，避免级联故障，以<strong>提高分布式系统的弹性。</strong></p>
<p>“断路器”本身是一种开关装置，当某个服务单元<strong>发生故障之后</strong>，通过断路器的故障监控（类似熔断保险丝），向调用方<strong>返回一个符合预期的、可处理的备选响应</strong>（FallBack），而不是长时间的等待或者抛出调用方无法处理的异常，这样就保证了服务调用方的线程不会被长时间、不必要地占用，从而<strong>避免了故障在分布式系统中的蔓延</strong>，乃至雪崩。</p>
<h3 id="10-1-3-Hystrix的作用"><a href="#10-1-3-Hystrix的作用" class="headerlink" title="10.1.3.Hystrix的作用"></a>10.1.3.Hystrix的作用</h3><p><em>服务</em>降级、<em>服务</em>熔断、<em>服务</em>限流、接近实时的监控等</p>
<h3 id="10-1-4-官网资料"><a href="#10-1-4-官网资料" class="headerlink" title="10.1.4.官网资料"></a>10.1.4.官网资料</h3><p><a target="_blank" rel="noopener" href="https://github.com/Netflix/Hystrix/wiki/How-To_Use">https://github.com/Netflix/Hystrix/wiki/How-To_Use</a></p>
<h3 id="10-1-5-Hystrix停更进维"><a href="#10-1-5-Hystrix停更进维" class="headerlink" title="10.1.5.Hystrix停更进维"></a>10.1.5.Hystrix停更进维</h3><p><a target="_blank" rel="noopener" href="https://github.com/Netflix/Hystrix">https://github.com/Netflix/Hystrix</a></p>
<p>官方推荐使用resilpience4j</p>
<p>Hystrix停更后，<strong>我们需要被动修复bug</strong></p>
<p>Hystrix不在发布新版本，也不再接收合并请求</p>
<h2 id="10-2-Hystrix重要概念（面试常考）"><a href="#10-2-Hystrix重要概念（面试常考）" class="headerlink" title="10.2.Hystrix重要概念（面试常考）"></a>10.2.Hystrix重要概念（面试常考）</h2><h3 id="10-2-1-服务降级"><a href="#10-2-1-服务降级" class="headerlink" title="10.2.1.服务降级"></a>10.2.1.服务降级</h3><p>当程序运行异常，不会让客户端等待，它会立刻返回一个友好的提示，fallback</p>
<blockquote>
<p>哪些情况下需要服务熔断</p>
</blockquote>
<ul>
<li>程序运行异常</li>
<li>超时</li>
<li>服务熔断除法服务降级</li>
<li>线程池/信号量打满也会导致服务降级</li>
</ul>
<h3 id="10-2-2-服务熔断"><a href="#10-2-2-服务熔断" class="headerlink" title="10.2.2.服务熔断"></a>10.2.2.服务熔断</h3><p>类似保险丝达到最大服务访问后，直接拒绝访问，拉闸限电，然后调用服务降级返回友好提示</p>
<h3 id="10-2-3-服务限流"><a href="#10-2-3-服务限流" class="headerlink" title="10.2.3.服务限流"></a>10.2.3.服务限流</h3><p>秒杀高并发等操作，严禁一窝蜂的过来拥挤，通过排队，每秒n个，有序进行访问</p>
<h2 id="10-3-Hystrix案例"><a href="#10-3-Hystrix案例" class="headerlink" title="10.3.Hystrix案例"></a>10.3.Hystrix案例</h2><h3 id="10-3-1-环境搭建"><a href="#10-3-1-环境搭建" class="headerlink" title="10.3.1.环境搭建"></a>10.3.1.环境搭建</h3><h4 id="1-新建cloud-provider-hystrix-payment8001"><a href="#1-新建cloud-provider-hystrix-payment8001" class="headerlink" title="1.新建cloud-provider-hystrix-payment8001"></a>1.新建cloud-provider-hystrix-payment8001</h4><h4 id="2-修改pom文件"><a href="#2-修改pom文件" class="headerlink" title="2.修改pom文件"></a>2.修改pom文件</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--        引入hystrix的起步依赖--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-hystrix<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--        引入eureka-client依赖--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-eureka-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--        引入web和actuator依赖--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-actuator<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span><span class="comment">&lt;!-- 引入自己定义的api通用包，可以使用Payment支付Entity --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.atyuan<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>cloud-api-commons<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;project.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-devtools<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>runtime<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">optional</span>&gt;</span>true<span class="tag">&lt;/<span class="name">optional</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.projectlombok<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>lombok<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">optional</span>&gt;</span>true<span class="tag">&lt;/<span class="name">optional</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="3-修改yml文件"><a href="#3-修改yml文件" class="headerlink" title="3.修改yml文件"></a>3.修改yml文件</h4><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">server:</span></span><br><span class="line">  <span class="attr">port:</span> <span class="number">8001</span></span><br><span class="line"></span><br><span class="line"><span class="attr">spring:</span></span><br><span class="line">  <span class="attr">application:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">cloud-provider-hystrix-payment</span></span><br><span class="line"></span><br><span class="line"><span class="attr">eureka:</span></span><br><span class="line">  <span class="attr">client:</span></span><br><span class="line">    <span class="attr">register-with-eureka:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">fetch-registry:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">service-url:</span></span><br><span class="line">      <span class="comment">#defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka</span></span><br><span class="line">      <span class="attr">defaultZone:</span> <span class="string">http://eureka7001.com:7001/eureka</span></span><br></pre></td></tr></table></figure>

<h4 id="4-创建启动类"><a href="#4-创建启动类" class="headerlink" title="4.创建启动类"></a>4.创建启动类</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="meta">@EnableEurekaClient</span> <span class="comment">//本服务启动后会自动注册进eureka服务中</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PaymentHystrixMain8001</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        SpringApplication.run(PaymentHystrixMain8001.class,args);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="5-业务类"><a href="#5-业务类" class="headerlink" title="5.业务类"></a>5.业务类</h4><blockquote>
<p>Service</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PaymentService</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 正常访问</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> id</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_OK</span><span class="params">(Integer id)</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;线程池: &quot;</span>+Thread.currentThread().getName() + <span class="string">&quot; paymentInfo_OK, id: &quot;</span>+id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_Timeout</span><span class="params">(Integer id)</span></span>&#123;</span><br><span class="line">        <span class="keyword">int</span> delayTime = <span class="number">3</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            TimeUnit.SECONDS.sleep(delayTime);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&quot;线程池: &quot;</span>+Thread.currentThread().getName() + <span class="string">&quot; paymentInfo_Timeout, id: &quot;</span>+id;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>controller</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PaymentController</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> PaymentService paymentService;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Value(&quot;$&#123;server.port&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">private</span> String serverPort;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/payment/hystrix/ok/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_OK</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        String result = paymentService.paymentInfo_OK(id);</span><br><span class="line">        log.info(<span class="string">&quot;result:&#123;&#125;&quot;</span>,result);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/payment/hystrix/timeout/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_TimeOut</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span>  </span>&#123;</span><br><span class="line">        String result = paymentService.paymentInfo_Timeout(id);</span><br><span class="line">        log.info(<span class="string">&quot;result:&#123;&#125;&quot;</span>,result);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="6-运行测试"><a href="#6-运行测试" class="headerlink" title="6.运行测试"></a>6.运行测试</h4><p>先启动eureka服务端7001,在启动当前项目</p>
<p>访问地址：<a target="_blank" rel="noopener" href="http://localhost:8001/payment/hystrix/ok/1">http://localhost:8001/payment/hystrix/ok/1</a></p>
<p>或<a target="_blank" rel="noopener" href="http://localhost:8001/payment/hystrix/timeout/1">http://localhost:8001/payment/hystrix/timeout/1</a></p>
<h3 id="10-3-2-高并发测试"><a href="#10-3-2-高并发测试" class="headerlink" title="10.3.2.高并发测试"></a>10.3.2.高并发测试</h3><h4 id="1-用JMeter模拟高并发"><a href="#1-用JMeter模拟高并发" class="headerlink" title="1.用JMeter模拟高并发"></a>1.用JMeter模拟高并发</h4><p>启动方式在bin目录下的jmeter.bat，如果出现java版本找不到的情况，需要在环境变量中修改path</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">变量名：【path】</span><br><span class="line"></span><br><span class="line">变量值：【\;%JAVA_HOME%\bin;%SystemRoot%/system32;%SystemRoot%;】 </span><br></pre></td></tr></table></figure>

<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203032054120.png" alt="image-20220303204026413"></p>
<p>模拟高并发</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203032044798.png" alt="image-20220303204245535"></p>
<p>配置ip、端口以及请求路径</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203032046738.png" alt="image-20220303204638611"></p>
<p>这个时候我们在浏览器中访问</p>
<p><a target="_blank" rel="noopener" href="http://localhost:8001/payment/hystrix/ok/1%E5%93%8D%E5%BA%94%E9%80%9F%E5%BA%A6%E4%B9%9F%E5%BC%80%E5%A7%8B%E5%8F%98%E6%85%A2%E4%BA%86">http://localhost:8001/payment/hystrix/ok/1响应速度也开始变慢了</a></p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203032052885.png" alt="image-20220303205234520"></p>
<p>这会影响到消费者的服务体验</p>
<h4 id="2-新建一个服务消费者增强高并发测试"><a href="#2-新建一个服务消费者增强高并发测试" class="headerlink" title="2.新建一个服务消费者增强高并发测试"></a>2.新建一个服务消费者增强高并发测试</h4><p>cloud-consumer-feign-hystrix-order8080</p>
<h5 id="（1）修改pom文件"><a href="#（1）修改pom文件" class="headerlink" title="（1）修改pom文件"></a>（1）修改pom文件</h5><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--openfeign--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-openfeign<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--hystrix--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-hystrix<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--eureka client--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-eureka-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 引入自己定义的api通用包，可以使用Payment支付Entity --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.atyuan<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>cloud-api-commons<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>$&#123;project.version&#125;<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--web--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-actuator<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--一般基础通用配置--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-devtools<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>runtime<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">optional</span>&gt;</span>true<span class="tag">&lt;/<span class="name">optional</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.projectlombok<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>lombok<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">optional</span>&gt;</span>true<span class="tag">&lt;/<span class="name">optional</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>test<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h5 id="（2）修改yml文件"><a href="#（2）修改yml文件" class="headerlink" title="（2）修改yml文件"></a>（2）修改yml文件</h5><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">server:</span></span><br><span class="line">  <span class="attr">port:</span> <span class="number">8080</span></span><br><span class="line"></span><br><span class="line"><span class="attr">eureka:</span></span><br><span class="line">  <span class="attr">client:</span></span><br><span class="line">    <span class="attr">register-with-eureka:</span> <span class="literal">false</span></span><br><span class="line">    <span class="attr">service-url:</span></span><br><span class="line">      <span class="attr">defaultZone:</span> <span class="string">http://eureka7001.com:7001/eureka/</span></span><br></pre></td></tr></table></figure>

<h5 id="（3）创建主启动类"><a href="#（3）创建主启动类" class="headerlink" title="（3）创建主启动类"></a>（3）创建主启动类</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="meta">@EnableFeignClients</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OrderHystrixMain80</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        SpringApplication.run(OrderHystrixMain80.class,args);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="（4）业务类"><a href="#（4）业务类" class="headerlink" title="（4）业务类"></a>（4）业务类</h5><blockquote>
<p>PaymentHystrixService</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@FeignClient(value = &quot;CLOUD-PROVIDER-HYSTRIX-PAYMENT&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">PaymentHystrixService</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="meta">@GetMapping(&quot;/payment/hystrix/ok/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="function">String <span class="title">paymentInfo_OK</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/payment/hystrix/timeout/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="function">String <span class="title">paymentInfo_TimeOut</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>OrderHystrixController</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OrderHystirxController</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> PaymentHystrixService paymentHystrixService;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/consumer/payment/hystrix/ok/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_OK</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        String result = paymentHystrixService.paymentInfo_OK(id);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/consumer/payment/hystrix/timeout/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_TimeOut</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        String result = paymentHystrixService.paymentInfo_TimeOut(id);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Jmeter使用高并发测试后，在浏览器通过8080端口访问测试</p>
<p><a target="_blank" rel="noopener" href="http://localhost:8080/consumer/payment/hystrix/ok/1">http://localhost:8080/consumer/payment/hystrix/ok/1</a></p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203032201151.png" alt="image-20220303220135553"></p>
<h3 id="10-3-3-故障现象和导致的原因"><a href="#10-3-3-故障现象和导致的原因" class="headerlink" title="10.3.3.故障现象和导致的原因"></a>10.3.3.故障现象和导致的原因</h3><p>故障现象：8080此时访问8001，客户端访问响应缓慢，转圈圈</p>
<p>导致原因：8001同一层次的其它接口服务被困死，因为tomcat线程池里面的工作线程已经被挤占完毕</p>
<h3 id="10-3-4-解决方法及要求"><a href="#10-3-4-解决方法及要求" class="headerlink" title="10.3.4.解决方法及要求"></a>10.3.4.解决方法及要求</h3><h4 id="1-超时导致请求响应变慢"><a href="#1-超时导致请求响应变慢" class="headerlink" title="1.超时导致请求响应变慢"></a>1.超时导致请求响应变慢</h4><p>解决方法：超时不再等待，调用回调方法</p>
<h4 id="2-解决"><a href="#2-解决" class="headerlink" title="2.解决"></a>2.解决</h4><p>对方服务（8001）<strong>超时</strong>，调用者（8080）不能一直卡死等待，必须有服务降级</p>
<p>对方服务（8001）<strong>宕机</strong>，调用者（8080）不能一直卡死等待，必须有服务降级</p>
<p>对方服务（8001）OK，调用者（8080）自己出故障，8080端口要有自己的回调方案</p>
<h3 id="10-3-5-服务降级"><a href="#10-3-5-服务降级" class="headerlink" title="10.3.5.服务降级"></a>10.3.5.服务降级</h3><h4 id="1-服务提供方"><a href="#1-服务提供方" class="headerlink" title="1.服务提供方"></a>1.服务提供方</h4><p>在8001提供者的服务方法设置回调方法，然后通过@HystrixCommand回调</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@HystrixCommand(fallbackMethod = &quot;paymentInfo_TimeoutHandler&quot;,commandProperties = &#123;</span></span><br><span class="line"><span class="meta">    @HystrixProperty(name=&quot;execution.isolation.thread.timeoutInMilliseconds&quot;,value = &quot;3000&quot;)</span></span><br><span class="line"><span class="meta">&#125;)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_Timeout</span><span class="params">(Integer id)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> delayTime = <span class="number">5</span>;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        TimeUnit.SECONDS.sleep(delayTime);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">        e.printStackTrace();</span><br><span class="line">    &#125;<span class="keyword">finally</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;线程池: &quot;</span>+Thread.currentThread().getName() + <span class="string">&quot; paymentInfo_Timeout, id: &quot;</span>+id;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_TimeoutHandler</span><span class="params">(Integer id)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;线程池: &quot;</span>+Thread.currentThread().getName() + <span class="string">&quot; 系统繁忙据哦运行出错，请稍后再试, id: &quot;</span>+id;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>启动类激活@HystrixCommand的使用</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@EnableCircu</span><span class="meta">@EnableCircuitBreaker</span></span><br></pre></td></tr></table></figure>

<h4 id="2-服务消费方"><a href="#2-服务消费方" class="headerlink" title="2.服务消费方"></a>2.服务消费方</h4><h5 id="（1）启动类上开启Hystrix注解支持"><a href="#（1）启动类上开启Hystrix注解支持" class="headerlink" title="（1）启动类上开启Hystrix注解支持"></a>（1）启动类上开启Hystrix注解支持</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@EnableHystrix</span></span><br></pre></td></tr></table></figure>

<h5 id="（2）业务类"><a href="#（2）业务类" class="headerlink" title="（2）业务类"></a>（2）业务类</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"> <span class="meta">@GetMapping(&quot;/consumer/payment/hystrix/timeout/&#123;id&#125;&quot;)</span></span><br><span class="line"><span class="meta">@HystrixCommand(fallbackMethod = &quot;paymentTimeOutFallbackMethod&quot;,commandProperties = &#123;</span></span><br><span class="line"><span class="meta">    @HystrixProperty(name=&quot;execution.isolation.thread.timeoutInMilliseconds&quot;,value=&quot;1500&quot;)</span></span><br><span class="line"><span class="meta">&#125;)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_TimeOut</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span>  </span>&#123;</span><br><span class="line">    String result = paymentService.paymentInfo_Timeout(id);</span><br><span class="line">    log.info(<span class="string">&quot;result:&#123;&#125;&quot;</span>,result);</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">paymentTimeOutFallbackMethod</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;我是消费者8080,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="10-3-5-服务降级仍存在的一个问题"><a href="#10-3-5-服务降级仍存在的一个问题" class="headerlink" title="10.3.5.服务降级仍存在的一个问题"></a>10.3.5.服务降级仍存在的一个问题</h3><p>代码膨胀，每一个业务方法对于一个回调方法，耦合度问题</p>
<h3 id="10-3-6-解决上述存在的问题"><a href="#10-3-6-解决上述存在的问题" class="headerlink" title="10.3.6.解决上述存在的问题"></a>10.3.6.解决上述存在的问题</h3><p>创建默认的回调方法，<strong>通过@DefalutProperties(defaultFallback=””)回调</strong></p>
<p><strong>通用的和独享的各自分开，避免了代码膨胀，合理减少了代码量</strong></p>
<p>controller配置</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="meta">@DefaultProperties(defaultFallback = &quot;payment_Global_FallbackMethod&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PaymentHystirxController</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> PaymentHystrixService paymentHystrixService;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/consumer/payment/hystrix/ok/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_OK</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        String result = paymentHystrixService.paymentInfo_OK(id);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/consumer/payment/hystrix/timeout/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="meta">@HystrixCommand</span> <span class="comment">//加了@DefaultProperties属性注解，并且没有写具体方法名字，就用统一全局的</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_TimeOut</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        String result = paymentHystrixService.paymentInfo_TimeOut(id);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentTimeOutFallbackMethod</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;paymentTimeOutFallbackMethod,对方系统繁忙，请10秒钟后再次尝试/(ㄒoㄒ)/&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">payment_Global_FallbackMethod</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Global异常处理信息，请稍后再试，/(ㄒoㄒ)/~~&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>但是这种方式还是耦合性强，没有实现业务代码和回调方法分离</p>
<h3 id="10-3-7-解决业务代码耦合问题"><a href="#10-3-7-解决业务代码耦合问题" class="headerlink" title="10.3.7.解决业务代码耦合问题"></a>10.3.7.解决业务代码耦合问题</h3><p>本次案例服务降级处理是在客户端80实现完成的，与服务端8001没有关系，只需要为Feign客户端定义的接口添加一个服务降级处理的实现类实现解耦</p>
<h4 id="1-创建消费端PaymentService接口的实现类"><a href="#1-创建消费端PaymentService接口的实现类" class="headerlink" title="1.创建消费端PaymentService接口的实现类"></a>1.创建消费端PaymentService接口的实现类</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PaymentServiceFallback</span> <span class="keyword">implements</span> <span class="title">PaymentService</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_OK</span><span class="params">(Integer id)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;8080端口 paymentInfo_OK服务调用失败&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">paymentInfo_Timeout</span><span class="params">(Integer id)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;8080端口 paymentInfo_Timeout服务调用失败&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="2-修改yml文件"><a href="#2-修改yml文件" class="headerlink" title="2.修改yml文件"></a>2.修改yml文件</h4><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 用于服务降级 在注解@FeignClient中添加fallbackFactory属性值</span></span><br><span class="line"><span class="attr">feign:</span></span><br><span class="line">  <span class="attr">hystrix:</span></span><br><span class="line">   <span class="attr">enabled:</span> <span class="literal">true</span> <span class="comment">#在Feign中开启Hystrix</span></span><br></pre></td></tr></table></figure>

<h4 id="3-服务消费方PaymentService接口"><a href="#3-服务消费方PaymentService接口" class="headerlink" title="3.服务消费方PaymentService接口"></a>3.服务消费方PaymentService接口</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@FeignClient(value = &quot;CLOUD-PROVIDER-HYSTRIX-PAYMENT&quot;,fallback = PaymentFallbackService.class)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">PaymentFeignClientService</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="meta">@GetMapping(&quot;/payment/hystrix/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getPaymentInfo</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="4-运行测试"><a href="#4-运行测试" class="headerlink" title="4.运行测试"></a>4.运行测试</h4><p>先启动7001，再启动8001，再启动8080</p>
<p>访问地址：<a target="_blank" rel="noopener" href="http://localhost:8080/consumer/payment/hystrix/ok/31">http://localhost:8080/consumer/payment/hystrix/ok/31</a></p>
<p>服务提供方8001关闭之前</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042135731.png" alt="image-20220303234444358"></p>
<p>这时，我们将8001关闭，使其无法访问提供方的业务方法</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042204632.png" alt="image-20220303234156463"></p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042134144.png" alt="image-20220303234125194"></p>
<h2 id="10-4-服务熔断"><a href="#10-4-服务熔断" class="headerlink" title="10.4.服务熔断"></a>10.4.服务熔断</h2><h3 id="10-4-1-断路器"><a href="#10-4-1-断路器" class="headerlink" title="10.4.1.断路器"></a>10.4.1.断路器</h3><p>相当于保险丝</p>
<h3 id="10-4-2-什么是熔断"><a href="#10-4-2-什么是熔断" class="headerlink" title="10.4.2.什么是熔断"></a>10.4.2.什么是熔断</h3><blockquote>
<p>熔断机制概述</p>
</blockquote>
<p>熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时，<br>会进行服务的降级，进而熔断该节点微服务的调用，快速返回错误的响应信息。<br><strong>当检测到该节点微服务调用响应正常后，恢复调用链路。</strong></p>
<p>在Spring Cloud框架里，熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况，当失败的调用到一定阈值，缺省是5秒内20次调用失败，就会启动熔断机制。<strong>熔断机制的注解是@HystrixCommand。</strong></p>
<p>官网：<a target="_blank" rel="noopener" href="https://martinfowler.com/bliki/CircuitBreaker.html">https://martinfowler.com/bliki/CircuitBreaker.html</a></p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042220342.png" alt="image-20220304222039881"></p>
<h3 id="10-4-5-修改cloud-provider-hystrix-payment8001的PaymentService"><a href="#10-4-5-修改cloud-provider-hystrix-payment8001的PaymentService" class="headerlink" title="10.4.5.修改cloud-provider-hystrix-payment8001的PaymentService"></a>10.4.5.修改cloud-provider-hystrix-payment8001的PaymentService</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">//=========服务熔断</span></span><br><span class="line"><span class="meta">@HystrixCommand(fallbackMethod = &quot;paymentCircuitBreaker_fallback&quot;,commandProperties = &#123;</span></span><br><span class="line"><span class="meta">    @HystrixProperty(name = &quot;circuitBreaker.enabled&quot;,value = &quot;true&quot;),</span></span><br><span class="line"><span class="meta">    @HystrixProperty(name = &quot;circuitBreaker.requestVolumeThreshold&quot;,value = &quot;10&quot;),</span></span><br><span class="line"><span class="meta">    @HystrixProperty(name = &quot;circuitBreaker.sleepWindowInMilliseconds&quot;,value = &quot;10000&quot;),</span></span><br><span class="line"><span class="meta">    @HystrixProperty(name = &quot;circuitBreaker.errorThresholdPercentage&quot;,value = &quot;60&quot;),</span></span><br><span class="line"><span class="meta">&#125;)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">paymentCircuitBreaker</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(id &lt; <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">&quot;******id 不能负数&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    String serialNumber = IdUtil.simpleUUID();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> Thread.currentThread().getName()+<span class="string">&quot;\t&quot;</span>+<span class="string">&quot;调用成功，流水号: &quot;</span> + serialNumber;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">paymentCircuitBreaker_fallback</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;id 不能负数，请稍后再试，/(ㄒoㄒ)/~~   id: &quot;</span> +id;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="10-4-6-修改Controller"><a href="#10-4-6-修改Controller" class="headerlink" title="10.4.6.修改Controller"></a>10.4.6.修改Controller</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@GetMapping(&quot;/payment/circuit/&#123;id&#125;&quot;)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">paymentCircuitBreaker</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Integer id)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    String result = paymentService.paymentCircuitBreaker(id);</span><br><span class="line">    log.info(<span class="string">&quot;****result: &quot;</span>+result);</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="10-4-7-测试"><a href="#10-4-7-测试" class="headerlink" title="10.4.7.测试"></a>10.4.7.测试</h3><p>自测cloud-provider-hystrix-payment8001</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042134564.png" alt="image-20220304213450674"></p>
<p>这是如果我们在10秒内访问10次<a target="_blank" rel="noopener" href="http://localhost:8001/payment/circuit/-10%E4%BC%9A%E5%87%BA%E7%8E%B0%E6%9C%8D%E5%8A%A1%E7%86%94%E6%96%AD%EF%BC%8C**%E7%84%B6%E5%90%8E%E5%9C%A8%E6%97%B6%E9%97%B4%E7%AA%97%E5%8F%A3%E6%9C%9F%E7%BB%93%E6%9D%9F5%E7%A7%92%E5%90%8E%E4%BC%9A%E5%BC%80%E5%90%AF%E5%8D%8A%E5%BC%80%E8%B7%AF%E7%8A%B6%E6%80%81%EF%BC%8C%E5%A6%82%E6%9E%9C%E8%AF%B7%E6%B1%82%E6%88%90%E5%8A%9F%EF%BC%8C%E5%88%99%E5%85%B3%E9%97%AD%E7%86%94%E6%96%AD%E3%80%82%E5%A6%82%E6%9E%9C%E8%AF%B7%E6%B1%82%E5%A4%B1%E8%B4%A5%EF%BC%8C%E5%88%99%E7%BB%A7%E7%BB%AD%E5%BC%80%E5%90%AF%E7%86%94%E6%96%AD">http://localhost:8001/payment/circuit/-10会出现服务熔断，**然后在时间窗口期结束5秒后会开启半开路状态，如果请求成功，则关闭熔断。如果请求失败，则继续开启熔断</a>**</p>
<p>断路器的窗口期内触发断路的<strong>请求阈值，默认为20</strong>。换句话说，假如某个窗口期内的请求总数都不到该配置值，那么断路器连发生的资格都没有。断路器在该窗口期内将不会被打开。</p>
<h3 id="10-4-8-原理"><a href="#10-4-8-原理" class="headerlink" title="10.4.8.原理"></a>10.4.8.原理</h3><h4 id="1-熔断类型"><a href="#1-熔断类型" class="headerlink" title="1.熔断类型"></a>1.熔断类型</h4><h5 id="（1）熔断打开"><a href="#（1）熔断打开" class="headerlink" title="（1）熔断打开"></a>（1）熔断打开</h5><p>请求不再进行调用当前服务，内部设置时钟一般为MTTR（平均故障处理时间），当打开时长达到所设时钟则进入版熔断状态</p>
<h5 id="（2）熔断关闭"><a href="#（2）熔断关闭" class="headerlink" title="（2）熔断关闭"></a>（2）熔断关闭</h5><p>熔断关闭不会对服务进行熔断</p>
<h5 id="（3）熔断半开"><a href="#（3）熔断半开" class="headerlink" title="（3）熔断半开"></a>（3）熔断半开</h5><p>部分请求根据规则调用当前服务，如果请求成功且符合规则则认为当前服务恢复正常，关闭熔断</p>
<h4 id="2-官网断路器流程图"><a href="#2-官网断路器流程图" class="headerlink" title="2.官网断路器流程图"></a>2.官网断路器流程图</h4><h5 id="（1）官网步骤"><a href="#（1）官网步骤" class="headerlink" title="（1）官网步骤"></a>（1）官网步骤</h5><p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042305123.png" alt="image-20220304230458378"></p>
<h5 id="（2）断路器在什么情况下开始起作用"><a href="#（2）断路器在什么情况下开始起作用" class="headerlink" title="（2）断路器在什么情况下开始起作用"></a>（2）断路器在什么情况下开始起作用</h5><p>涉及到断路器的三个重要参数：<strong>快照时间窗、请求总数阀值、错误百分比阀值。</strong></p>
<p>1：快照时间窗：断路器确定是否打开需要统计一些请求和错误数据，而统计的时间范围就是快照时间窗，默认为最近的10秒。</p>
<p>2：请求总数阀值：在快照时间窗内，必须满足请求总数阀值才有资格熔断。默认为20，意味着在10秒内，如果该hystrix命令的调用次数不足20次，即使所有的请求都超时或其他原因失败，断路器都不会打开。</p>
<p>3：错误百分比阀值：当请求总数在快照时间窗内超过了阀值，比如发生了30次调用，如果在这30次调用中，有15次发生了超时异常，也就是超过50%的错误百分比，在默认设定50%阀值情况下，这时候就会将断路器打开。</p>
<h5 id="（3）断路器开启或关闭的条件"><a href="#（3）断路器开启或关闭的条件" class="headerlink" title="（3）断路器开启或关闭的条件"></a>（3）断路器开启或关闭的条件</h5><p>默认情况下，在10秒内超过20个请求次数，且超过50%的失败率，断路器就会开启</p>
<p>在开启之后，所有请求都不会进行转发</p>
<p>一段时间后（默认5秒），这个时候断路器是半开状态，会让其中一个请求进行转发，若成功，断路器会关闭。若失败，继续开启。然后又过5秒进行相同的操作</p>
<h5 id="（4）断路器打开之后"><a href="#（4）断路器打开之后" class="headerlink" title="（4）断路器打开之后"></a>（4）断路器打开之后</h5><p>1：再有请求调用的时候，将不会调用主逻辑，而是直接调用降级fallback。通过断路器，实现了自动地发现错误并将降级逻辑切换为主逻辑，减少响应延迟的效果。</p>
<p>2：原来的主逻辑要如何恢复呢？<br>对于这一问题，hystrix也为我们实现了自动恢复功能。当断路器打开，对主逻辑进行熔断之后，hystrix会启动一个休眠时间窗，在这个时间窗内，降级逻辑是临时的成为主逻辑，当休眠时间窗到期，断路器将进入半开状态，释放一次请求到原来的主逻辑上，如果此次请求正常返回，那么断路器将继续闭合，主逻辑恢复，如果这次请求依然有问题，断路器继续进入打开状态，休眠时间窗重新计时。</p>
<h5 id="（5）HystrixProperties的所有配置"><a href="#（5）HystrixProperties的所有配置" class="headerlink" title="（5）HystrixProperties的所有配置"></a>（5）HystrixProperties的所有配置</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@HystrixCommand(fallbackMethod = &quot;str_fallbackMethod&quot;,</span></span><br><span class="line"><span class="meta">        groupKey = &quot;strGroupCommand&quot;,</span></span><br><span class="line"><span class="meta">        commandKey = &quot;strCommand&quot;,</span></span><br><span class="line"><span class="meta">        threadPoolKey = &quot;strThreadPool&quot;,</span></span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">        commandProperties = &#123;</span></span><br><span class="line"><span class="meta">                // 设置隔离策略，THREAD 表示线程池 SEMAPHORE：信号池隔离</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;execution.isolation.strategy&quot;, value = &quot;THREAD&quot;),</span></span><br><span class="line"><span class="meta">                // 当隔离策略选择信号池隔离的时候，用来设置信号池的大小（最大并发数）</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;execution.isolation.semaphore.maxConcurrentRequests&quot;, value = &quot;10&quot;),</span></span><br><span class="line"><span class="meta">                // 配置命令执行的超时时间</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;execution.isolation.thread.timeoutinMilliseconds&quot;, value = &quot;10&quot;),</span></span><br><span class="line"><span class="meta">                // 是否启用超时时间</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;execution.timeout.enabled&quot;, value = &quot;true&quot;),</span></span><br><span class="line"><span class="meta">                // 执行超时的时候是否中断</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;execution.isolation.thread.interruptOnTimeout&quot;, value = &quot;true&quot;),</span></span><br><span class="line"><span class="meta">                // 执行被取消的时候是否中断</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;execution.isolation.thread.interruptOnCancel&quot;, value = &quot;true&quot;),</span></span><br><span class="line"><span class="meta">                // 允许回调方法执行的最大并发数</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;fallback.isolation.semaphore.maxConcurrentRequests&quot;, value = &quot;10&quot;),</span></span><br><span class="line"><span class="meta">                // 服务降级是否启用，是否执行回调函数</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;fallback.enabled&quot;, value = &quot;true&quot;),</span></span><br><span class="line"><span class="meta">                // 是否启用断路器</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;circuitBreaker.enabled&quot;, value = &quot;true&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置在滚动时间窗中，断路器熔断的最小请求数。例如，默认该值为 20 的时候，</span></span><br><span class="line"><span class="meta">                // 如果滚动时间窗（默认10秒）内仅收到了19个请求， 即使这19个请求都失败了，断路器也不会打开。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;circuitBreaker.requestVolumeThreshold&quot;, value = &quot;20&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置在滚动时间窗中，表示在滚动时间窗中，在请求数量超过</span></span><br><span class="line"><span class="meta">                // circuitBreaker.requestVolumeThreshold 的情况下，如果错误请求数的百分比超过50,</span></span><br><span class="line"><span class="meta">                // 就把断路器设置为 &quot;打开&quot; 状态，否则就设置为 &quot;关闭&quot; 状态。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;circuitBreaker.errorThresholdPercentage&quot;, value = &quot;50&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置当断路器打开之后的休眠时间窗。 休眠时间窗结束之后，</span></span><br><span class="line"><span class="meta">                // 会将断路器置为 &quot;半开&quot; 状态，尝试熔断的请求命令，如果依然失败就将断路器继续设置为 &quot;打开&quot; 状态，</span></span><br><span class="line"><span class="meta">                // 如果成功就设置为 &quot;关闭&quot; 状态。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;circuitBreaker.sleepWindowinMilliseconds&quot;, value = &quot;5000&quot;),</span></span><br><span class="line"><span class="meta">                // 断路器强制打开</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;circuitBreaker.forceOpen&quot;, value = &quot;false&quot;),</span></span><br><span class="line"><span class="meta">                // 断路器强制关闭</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;circuitBreaker.forceClosed&quot;, value = &quot;false&quot;),</span></span><br><span class="line"><span class="meta">                // 滚动时间窗设置，该时间用于断路器判断健康度时需要收集信息的持续时间</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;metrics.rollingStats.timeinMilliseconds&quot;, value = &quot;10000&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置滚动时间窗统计指标信息时划分&quot;桶&quot;的数量，断路器在收集指标信息的时候会根据</span></span><br><span class="line"><span class="meta">                // 设置的时间窗长度拆分成多个 &quot;桶&quot; 来累计各度量值，每个&quot;桶&quot;记录了一段时间内的采集指标。</span></span><br><span class="line"><span class="meta">                // 比如 10 秒内拆分成 10 个&quot;桶&quot;收集这样，所以 timeinMilliseconds 必须能被 numBuckets 整除。否则会抛异常</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;metrics.rollingStats.numBuckets&quot;, value = &quot;10&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置对命令执行的延迟是否使用百分位数来跟踪和计算。如果设置为 false, 那么所有的概要统计都将返回 -1。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;metrics.rollingPercentile.enabled&quot;, value = &quot;false&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置百分位统计的滚动窗口的持续时间，单位为毫秒。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;metrics.rollingPercentile.timeInMilliseconds&quot;, value = &quot;60000&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置百分位统计滚动窗口中使用 “ 桶 ”的数量。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;metrics.rollingPercentile.numBuckets&quot;, value = &quot;60000&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置在执行过程中每个 “桶” 中保留的最大执行次数。如果在滚动时间窗内发生超过该设定值的执行次数，</span></span><br><span class="line"><span class="meta">                // 就从最初的位置开始重写。例如，将该值设置为100, 滚动窗口为10秒，若在10秒内一个 “桶 ”中发生了500次执行，</span></span><br><span class="line"><span class="meta">                // 那么该 “桶” 中只保留 最后的100次执行的统计。另外，增加该值的大小将会增加内存量的消耗，并增加排序百分位数所需的计算时间。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;metrics.rollingPercentile.bucketSize&quot;, value = &quot;100&quot;),</span></span><br><span class="line"><span class="meta">                // 该属性用来设置采集影响断路器状态的健康快照（请求的成功、 错误百分比）的间隔等待时间。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;metrics.healthSnapshot.intervalinMilliseconds&quot;, value = &quot;500&quot;),</span></span><br><span class="line"><span class="meta">                // 是否开启请求缓存</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;requestCache.enabled&quot;, value = &quot;true&quot;),</span></span><br><span class="line"><span class="meta">                // HystrixCommand的执行和事件是否打印日志到 HystrixRequestLog 中</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;requestLog.enabled&quot;, value = &quot;true&quot;),</span></span><br><span class="line"><span class="meta">        &#125;,</span></span><br><span class="line"><span class="meta">        threadPoolProperties = &#123;</span></span><br><span class="line"><span class="meta">                // 该参数用来设置执行命令线程池的核心线程数，该值也就是命令执行的最大并发量</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;coreSize&quot;, value = &quot;10&quot;),</span></span><br><span class="line"><span class="meta">                // 该参数用来设置线程池的最大队列大小。当设置为 -1 时，线程池将使用 SynchronousQueue 实现的队列，</span></span><br><span class="line"><span class="meta">                // 否则将使用 LinkedBlockingQueue 实现的队列。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;maxQueueSize&quot;, value = &quot;-1&quot;),</span></span><br><span class="line"><span class="meta">                // 该参数用来为队列设置拒绝阈值。 通过该参数， 即使队列没有达到最大值也能拒绝请求。</span></span><br><span class="line"><span class="meta">                // 该参数主要是对 LinkedBlockingQueue 队列的补充,因为 LinkedBlockingQueue</span></span><br><span class="line"><span class="meta">                // 队列不能动态修改它的对象大小，而通过该属性就可以调整拒绝请求的队列大小了。</span></span><br><span class="line"><span class="meta">                @HystrixProperty(name = &quot;queueSizeRejectionThreshold&quot;, value = &quot;5&quot;),</span></span><br><span class="line"><span class="meta">        &#125;</span></span><br><span class="line"><span class="meta">)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">strConsumer</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;hello 2020&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">str_fallbackMethod</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;*****fall back str_fallbackMethod&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="10-5-Hystrix工作流程"><a href="#10-5-Hystrix工作流程" class="headerlink" title="10.5.Hystrix工作流程"></a>10.5.Hystrix工作流程</h2><p><a target="_blank" rel="noopener" href="https://github.com/Netflix/Hystrix/wiki/How-it-Works">https://github.com/Netflix/Hystrix/wiki/How-it-Works</a></p>
<p>官网案例：</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042316548.png" alt="image-20220304231628227"></p>
<p>步骤说明</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042317982.png" alt="image-20220304231743455"></p>
<h2 id="10-6-服务监控（hystrixDashboard）"><a href="#10-6-服务监控（hystrixDashboard）" class="headerlink" title="10.6.服务监控（hystrixDashboard）"></a>10.6.服务监控（hystrixDashboard）</h2><h3 id="10-6-1-概述"><a href="#10-6-1-概述" class="headerlink" title="10.6.1.概述"></a>10.6.1.概述</h3><p>除了隔离依赖服务的调用以外，Hystrix还提供了准实时的调用监控（Hystrix Dashboard），Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息，并以统计报表和图形的形式展示给用户，包括每秒执行多少请求多少成功，多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合，对监控内容转化成可视化界面。</p>
<h3 id="10-6-2-仪表盘9001"><a href="#10-6-2-仪表盘9001" class="headerlink" title="10.6.2.仪表盘9001"></a>10.6.2.仪表盘9001</h3><h4 id="1-新建cloud-consumer-hystrix-payment9001模块"><a href="#1-新建cloud-consumer-hystrix-payment9001模块" class="headerlink" title="1.新建cloud-consumer-hystrix-payment9001模块"></a>1.新建cloud-consumer-hystrix-payment9001模块</h4><h4 id="2-修改pom文件-1"><a href="#2-修改pom文件-1" class="headerlink" title="2.修改pom文件"></a>2.修改pom文件</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-hystrix-dashboard<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-actuator<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-devtools<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>runtime<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">optional</span>&gt;</span>true<span class="tag">&lt;/<span class="name">optional</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.projectlombok<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>lombok<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">optional</span>&gt;</span>true<span class="tag">&lt;/<span class="name">optional</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>test<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="3-写yml文件"><a href="#3-写yml文件" class="headerlink" title="3.写yml文件"></a>3.写yml文件</h4><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">server:</span></span><br><span class="line">  <span class="attr">port:</span> <span class="number">9001</span></span><br><span class="line"><span class="attr">hystrix:</span></span><br><span class="line">  <span class="attr">dashboard:</span></span><br><span class="line">    <span class="attr">proxy-stream-allow-list:</span> <span class="string">&quot;localhost&quot;</span></span><br></pre></td></tr></table></figure>

<h4 id="4-创建启动类-1"><a href="#4-创建启动类-1" class="headerlink" title="4.创建启动类"></a>4.创建启动类</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="meta">@EnableHystrixDashboard</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HystrixDashboardMain9001</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        SpringApplication.run(HystrixDashboardMain9001.class,args);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="5-微服务提供者需要监控依赖"><a href="#5-微服务提供者需要监控依赖" class="headerlink" title="5.微服务提供者需要监控依赖"></a>5.微服务提供者需要监控依赖</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">   <span class="comment">&lt;!-- actuator监控信息完善 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-actuator<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>此时我们就可以通过<a target="_blank" rel="noopener" href="http://localhost:9001/hystrix%E6%9F%A5%E7%9C%8Bhystrix%E7%9A%84%E5%9B%BE%E5%BD%A2%E5%8C%96%E7%95%8C%E9%9D%A2">http://localhost:9001/hystrix查看hystrix的图形化界面</a></p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042345861.png" alt="image-20220304234526123"></p>
<h3 id="10-6-3-监控测试"><a href="#10-6-3-监控测试" class="headerlink" title="10.6.3.监控测试"></a>10.6.3.监控测试</h3><p>修改cloud-provider-hystrix-payment8001的启动类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *此配置是为了服务监控而配置，与服务容错本身无关，springcloud升级后的坑</span></span><br><span class="line"><span class="comment"> *ServletRegistrationBean因为springboot的默认路径不是&quot;/hystrix.stream&quot;，</span></span><br><span class="line"><span class="comment"> *只要在自己的项目里配置上下面的servlet就可以了</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> ServletRegistrationBean <span class="title">getServlet</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    HystrixMetricsStreamServlet streamServlet = <span class="keyword">new</span> HystrixMetricsStreamServlet();</span><br><span class="line">    ServletRegistrationBean registrationBean = <span class="keyword">new</span> ServletRegistrationBean(streamServlet);</span><br><span class="line">    registrationBean.setLoadOnStartup(<span class="number">1</span>);</span><br><span class="line">    registrationBean.addUrlMappings(<span class="string">&quot;/hystrix.stream&quot;</span>);</span><br><span class="line">    registrationBean.setName(<span class="string">&quot;HystrixMetricsStreamServlet&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> registrationBean;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>启动一个eureka服务注册中心</p>
<p>然后启动8001端口</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042345938.png" alt="image-20220304234554160"></p>
<p>注意：如果进入监控页面，显示的是unable to connect command metric stream需要在9001配置文件加上</p>
<figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">hystrix:</span></span><br><span class="line">  <span class="attr">dashboard:</span></span><br><span class="line">    <span class="attr">proxy-stream-allow-list:</span> <span class="string">&quot;localhost&quot;</span></span><br></pre></td></tr></table></figure>

<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203042349471.png" alt="image-20220304234906048"></p>
<p>断路器打开</p>
<p>图表说明</p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203050002303.png" alt="image-20220305000235191"></p>
<p><img src="https://gitee.com/RMByuan/note-material/raw/master/studyImg/202203050003424.png" alt="image-20220305000306456"></p>
<h1 id=""><a href="#" class="headerlink" title=""></a></h1> 
      <!-- reward -->
      
      <div id="reword-out">
        <div id="reward-btn">
          打赏
        </div>
      </div>
      
    </div>
    

    <!-- copyright -->
    
    <div class="declare">
      <ul class="post-copyright">
        <li>
          <i class="ri-copyright-line"></i>
          <strong>版权声明： </strong>
          
          本博客所有文章除特别声明外，著作权归作者所有。转载请注明出处！
          
        </li>
      </ul>
    </div>
    
    <footer class="article-footer">
       
<div class="share-btn">
      <span class="share-sns share-outer">
        <i class="ri-share-forward-line"></i>
        分享
      </span>
      <div class="share-wrap">
        <i class="arrow"></i>
        <div class="share-icons">
          
          <a class="weibo share-sns" href="javascript:;" data-type="weibo">
            <i class="ri-weibo-fill"></i>
          </a>
          <a class="weixin share-sns wxFab" href="javascript:;" data-type="weixin">
            <i class="ri-wechat-fill"></i>
          </a>
          <a class="qq share-sns" href="javascript:;" data-type="qq">
            <i class="ri-qq-fill"></i>
          </a>
          <a class="douban share-sns" href="javascript:;" data-type="douban">
            <i class="ri-douban-line"></i>
          </a>
          <!-- <a class="qzone share-sns" href="javascript:;" data-type="qzone">
            <i class="icon icon-qzone"></i>
          </a> -->
          
          <a class="facebook share-sns" href="javascript:;" data-type="facebook">
            <i class="ri-facebook-circle-fill"></i>
          </a>
          <a class="twitter share-sns" href="javascript:;" data-type="twitter">
            <i class="ri-twitter-fill"></i>
          </a>
          <a class="google share-sns" href="javascript:;" data-type="google">
            <i class="ri-google-fill"></i>
          </a>
        </div>
      </div>
</div>

<div class="wx-share-modal">
    <a class="modal-close" href="javascript:;"><i class="ri-close-circle-line"></i></a>
    <p>扫一扫，分享到微信</p>
    <div class="wx-qrcode">
      <img src="//api.qrserver.com/v1/create-qr-code/?size=150x150&data=http://example.com/2022/03/12/SpringCloud-Hystrix%E6%96%AD%E8%B7%AF%E5%99%A8/" alt="微信分享二维码">
    </div>
</div>

<div id="share-mask"></div>  
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/SpringCloud/" rel="tag">SpringCloud</a></li></ul>

    </footer>
  </div>

   
  <nav class="article-nav">
    
      <a href="/2022/03/12/SpringCloud%E7%AC%94%E8%AE%B0/" class="article-nav-link">
        <strong class="article-nav-caption">上一篇</strong>
        <div class="article-nav-title">
          
            SpringCloud笔记
          
        </div>
      </a>
    
    
      <a href="/2022/03/05/Spring5%E6%96%B0%E5%8A%9F%E8%83%BD/" class="article-nav-link">
        <strong class="article-nav-caption">下一篇</strong>
        <div class="article-nav-title">Spring5新功能</div>
      </a>
    
  </nav>

   
<!-- valine评论 -->
<div id="vcomments-box">
  <div id="vcomments"></div>
</div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js"></script>
<script>
  new Valine({
    el: "#vcomments",
    app_id: "",
    app_key: "",
    path: window.location.pathname,
    avatar: "monsterid",
    placeholder: "给我的文章加点评论吧~",
    recordIP: true,
  });
  const infoEle = document.querySelector("#vcomments .info");
  if (infoEle && infoEle.childNodes && infoEle.childNodes.length > 0) {
    infoEle.childNodes.forEach(function (item) {
      item.parentNode.removeChild(item);
    });
  }
</script>
<style>
  #vcomments-box {
    padding: 5px 30px;
  }

  @media screen and (max-width: 800px) {
    #vcomments-box {
      padding: 5px 0px;
    }
  }

  #vcomments-box #vcomments {
    background-color: #fff;
  }

  .v .vlist .vcard .vh {
    padding-right: 20px;
  }

  .v .vlist .vcard {
    padding-left: 10px;
  }
</style>

 
   
     
</article>

</section>
      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2015-2022
        <i class="ri-heart-fill heart_icon"></i> Yuan
      </li>
    </ul>
    <ul>
      <li>
        
      </li>
    </ul>
    <ul>
      <li>
        
        
        <span>
  <span><i class="ri-user-3-fill"></i>访问人数:<span id="busuanzi_value_site_uv"></span></span>
  <span class="division">|</span>
  <span><i class="ri-eye-fill"></i>浏览次数:<span id="busuanzi_value_page_pv"></span></span>
</span>
        
      </li>
    </ul>
    <ul>
      
    </ul>
    <ul>
      
    </ul>
    <ul>
      <li>
        <!-- cnzz统计 -->
        
        <script type="text/javascript" src='https://s9.cnzz.com/z_stat.php?id=1278069914&amp;web_id=1278069914'></script>
        
      </li>
    </ul>
  </div>
</footer>    
    </main>
    <div class="float_btns">
      <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>

<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>

    </div>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="/images/ayer-side.svg" alt="MyBlog"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/tags">标签</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/friends">友链</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/about">关于我</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="搜索">
        <i class="ri-search-line"></i>
      </a>
      
      
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    
  </div>
</div>
    
<script src="/js/jquery-3.6.0.min.js"></script>
 
<script src="/js/lazyload.min.js"></script>

<!-- Tocbot -->
 
<script src="/js/tocbot.min.js"></script>

<script>
  tocbot.init({
    tocSelector: ".tocbot",
    contentSelector: ".article-entry",
    headingSelector: "h1, h2, h3, h4, h5, h6",
    hasInnerContainers: true,
    scrollSmooth: true,
    scrollContainer: "main",
    positionFixedSelector: ".tocbot",
    positionFixedClass: "is-position-fixed",
    fixedSidebarOffset: "auto",
  });
</script>

<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css"
/>
<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js"></script>

<script src="/dist/main.js"></script>

<!-- ImageViewer -->
 <!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script> 
<!-- MathJax -->

<!-- Katex -->

<!-- busuanzi  -->
 
<script src="/js/busuanzi-2.3.pure.min.js"></script>
 
<!-- ClickLove -->
 
<script src="/js/clickLove.js"></script>
 
<!-- ClickBoom1 -->

<!-- ClickBoom2 -->

<!-- CodeCopy -->
 
<link rel="stylesheet" href="/css/clipboard.css">
 <script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="ri-file-copy-2-line"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-checkbox-circle-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-checkbox-circle-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-time-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-time-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>
 
<!-- CanvasBackground -->

<script>
  if (window.mermaid) {
    mermaid.initialize({ theme: "forest" });
  }
</script>


    
    <div id="music">
    
    
    
    <iframe frameborder="no" border="1" marginwidth="0" marginheight="0" width="200" height="52"
        src="//music.163.com/outchain/player?type=2&id=22707008&auto=1&height=32"></iframe>
</div>

<style>
    #music {
        position: fixed;
        right: 15px;
        bottom: 0;
        z-index: 998;
    }
</style>
    
    

  </div>
</body>

</html>